import { Injectable, Inject } from '@angular/core';

import { ApplicationEnv, } from '../keys';

@Injectable({
  providedIn: 'root'
})
export class LoggerService {

  private _consoleError;

  constructor(
    private applicationEnv: ApplicationEnv
  ) { }

  public rewriteNativeMethod() {
    if (this._consoleError) {
      return;
    }

    window.onerror = this.reportOnError.bind(this);
    this._consoleError = window.console.error.bind(window.console);
    window.console.error = this.consoleError.bind(this);
  }

  public warn(message: string, flag?: string) {
    this.report(['warn', flag, message].join('|||'));
    // tslint:disable-next-line:no-console
    console.warn(message);
    message = this.wrapMessage(message, flag);
  }

  public error(e: Error, flag?: string) {
    this.report(['error', flag, e.message, e.stack].join('|||'));
    e.message = this.wrapMessage(e.message, flag);
    if (this._consoleError) {
      this._consoleError(e);
    } else {
      window.console.error(e);
    }
  }

  public report(data: any) {
    if (this.applicationEnv.production && this.applicationEnv.reportUrl) {
      const message = [navigator.userAgent, Date.now(), data].join('|||');
      const img = new Image();
      img.src = this.applicationEnv.reportUrl + '?' + message;
    }

    return true;
  }

  private reportOnError(msg, url, line, col, error) {
    const _error = Object.assign(error);
    _error.message = [msg, url, line, col].join('|');
    this.error(_error, 'unknown');
  }

  private consoleError(message: string, ...rest) {
    // 屏蔽ajax请求业务异常报错
    if (rest && rest[0] && rest[0].rejection && rest[0].rejection._noErrorConsole) {
      //
    } else if (rest && rest[0] instanceof Error) {
      this.error(rest[0], 'console');
    } else {
      this.error(new Error([message, ...rest].join('')), 'console');
    }
  }

  private wrapMessage(message, flag) {
    if (flag) {
      return message + ' ---> ' + flag;
    }
    return message;
  }
}
